<?php if ( ! defined('BASEPATH')) exit('No direct script access allowed');

/*
 * $Id: permission.php 187 2012-03-11 08:40:12Z leikou@163.com $
 */

/**
 * Permission module.
 *
 * Include permisson configuration, account management, 
 * access log and so on
 *
 */


class Permission extends OA_Controller
{
    const CATAGORY = OA_CONST_CATAGORY::PERMISSION;


    /**
     * @name 角色展示
     * @desc 权限配置功能角色展示
     */
    public function role_display()
    {
        // Get all role info
        $role_db_obj = $this->db->select('*')->from('role');

        // Only master can see permission role
        if( ! $this->session->is_master())
        {
            $role_db_obj->where('catagory_id !=', OA_CONST_CATAGORY::PERMISSION);
        }

        $query = $role_db_obj->get();

        $result = $query->result_array();

        //Group by catagory id in php
        $role_dict = array();
        foreach($result as $row)
        {
            $role_dict[$row['catagory_id']][] = $row;
        }

        // Get catagory info
        $catagory_db_obj = $this->db->from('catagory');

        // Only master can see permission catagory;
        if( ! $this->session->is_master())
        {
            $catagory_db_obj->where('id !=', OA_CONST_CATAGORY::PERMISSION);
        }

        $query = $catagory_db_obj->get();

        $result = $query->result_array();
        $catagory_dict = array();
        foreach($result as $row)
        {
            $catagory_dict[$row['id']] = $row['title'];
        }

        $this->load->view('permission_role_display', array(
            'role_dict' => $role_dict,
            'catagory_dict' => $catagory_dict,
        ));
    }


    /**
     * @name controller类/方法展示
     * @desc 权限配置功能controller类/方法展示
     */
    public function class_func_display()
    {
        list($data) = $this->check(array(
            'role_id' => FC_int('角色')->min(1)->required(),    
        ));

        // Get allowed catagory id, only same catagory controller
        // and common controller can be set
        $role_db_obj = $this->db
            ->select('catagory_id')
            ->from('role')
            ->where('id', $data['role_id']);

        if( ! $this->session->is_master())
        {
            $role_db_obj->where('catagory_id !=', OA_CONST_CATAGORY::PERMISSION);            
        }

        $query = $role_db_obj->get();

        $role_info = $query->row_array();
        if(empty($role_info))
        {
            show_error('您要设置的角色非法');
        }

        $allowed_catagory_ids = array(
            intval($role_info['catagory_id']),
            OA_CONST_CATAGORY::COMMON,
        );

        // Get all controller class function
        $query = $this->db
            ->select('cf.id, cf.name, cf.description, cf.catagory_id, r.r_id')
            ->from('class_func_description AS cf')
            ->join(
                'class_func_role AS r', 
                'cf.id = r.cf_id AND r.r_id = '.$data['role_id'], 
                'left'
            )
            ->where_in('cf.catagory_id', $allowed_catagory_ids)
            ->get();

        $result = $query->result_array();

        // Group by catagory id in php
        $class_func_dict = array();
        foreach($result as $row)
        {
            $class_func_dict[$row['catagory_id']][] = $row;
        }

        // Get catagory info
        $query = $this->db
            ->from('catagory')
            ->get();

        $result = $query->result_array();
        $catagory_dict = array();
        foreach($result as $row)
        {
            $catagory_dict[$row['id']] = $row['title'];
        }

        $this->load->view('permission_class_func_display', array(
            'class_func_dict' => $class_func_dict,
            'catagory_dict' => $catagory_dict,
            'role_id' => $data['role_id'],
            'token_name' => $this->security->get_csrf_token_name(),
            'token_hash' => $this->security->get_csrf_hash(),
        ));
    }

    
    /**
     * @name 角色功能关联
     * @desc 权限模块，角色功能关联
     * @method post
     */
    public function class_func_role_set()
    {
        list($safe_vars) = $this->check(array(
            'role_id' => FC_int('角色')->min(1)->required(),
            'cf_id' => FC_int('功能')->multi(),
        ));
        $safe_vars['cf_id'] = array_unique($safe_vars['cf_id']);

        // Check role_id
        $role_db_obj = $this->db
            ->select('catagory_id')
            ->from('role')
            ->where('id', $safe_vars['role_id']);

        if( ! $this->session->is_master())
        {
            $role_db_obj->where('catagory_id !=', OA_CONST_CATAGORY::PERMISSION);
        }

        $query = $role_db_obj->get();

        $role_info = $query->row_array();
        if(empty($role_info))
        {
            show_error('很抱歉，您要设置的角色不存在');
        }

        // Get old ids
        $query = $this->db
            ->from('class_func_role')
            ->where('r_id', $safe_vars['role_id'])
            ->get();
        $old_cf_info = $query->result_array();

        $old_ids = array();
        foreach($old_cf_info as $info)
        {
            $old_ids[] = $info['cf_id'];
        }

        $old_new_diff = array_diff($old_ids, $safe_vars['cf_id']);
        $new_old_diff = array_diff($safe_vars['cf_id'], $old_ids);
        if(empty($old_new_diff) && empty($new_old_diff))
        {
            // Show info page: noting changes
            $this->load->view('info', array(
                'message' => '您没有做任何变更',
            ));
            return;
        }

        $allowed_catagory_ids = array(
            intval($role_info['catagory_id']),
            OA_CONST_CATAGORY::COMMON,
        );

        if($safe_vars['cf_id'])
        {
            $count = $this->db
                ->select('id')
                ->from('class_func_description')
                ->where_in('id', $safe_vars['cf_id'])
                ->where_in('catagory_id', $allowed_catagory_ids)
                ->count_all_results();

            if($count !== count($safe_vars['cf_id']))
            {
                show_error('很抱歉，您要设置的功能错误');
            }
        }

        $this->db->trans_start();
        // Delete role_id related controller class/func id
        $this->db
            ->where('r_id', $safe_vars['role_id'])
            ->delete('class_func_role');
            
        // Insert class/func id for role_id
        if($safe_vars['cf_id'])
        {
            $insert_data = array();
            foreach($safe_vars['cf_id'] as $cf_id)
            {
                $insert_data[] = array(
                    'r_id' => $safe_vars['role_id'],
                    'cf_id' => $cf_id,
                );
            }
            $this->db->insert_batch('class_func_role', $insert_data);
        }

        // Log
        $query = $this->db
            ->select('id')
            ->from('class_func_description')
            ->where('class', __CLASS__)
            ->where('func', __FUNCTION__)
            ->get();

        $self_cf_info = $query->first_row('array');

        $log_message = array(
            'role_id' => $safe_vars['role_id'],
            'old_cf_id' => $old_ids,
            'new_cf_id' => $safe_vars['cf_id'],
        );

        $this->db->insert('permission_log', array(
            'u_id' => $this->session->get_uid(),
            'cf_id' => $self_cf_info['id'],
            'message' => json_encode($log_message),
            'dateline' => time()
        ));

        $this->db->trans_complete();

        // Show success info page
        $this->load->view('info', array(
            'message' => '变更成功',
        ));
    }


    /**
     * @name 权限变更记录
     * @desc 权限模块，显示权限变更记录
     */
    public function change_log_list()
    {
        list($safe_vars) = $this->check(array(
            'uid' => FC_int('工号')->min(1),
            'username' => FC_str('用户名')->min(5)->max(20),
            'begin_date' => FC_date('开始日期', "Y-m-d"),
            'end_date' => FC_date('结束日期', "Y-m-d"),
            'page' => FC_int('页码', 1)->min(1),
        ));

        // Set where condition
        $where = array();
        if($safe_vars['uid'])
        {
            $where['u.id'] = $safe_vars['uid'];
        }

        if($safe_vars['username'])
        {
            $where['u.username'] = $safe_vars['username'];
        }

        if($safe_vars['begin_date'])
        {
            $where['p.dateline >='] = intval(strtotime($safe_vars['begin_date']));
        }

        if($safe_vars['end_date'])
        {
            $where['p.dateline <='] = intval(strtotime($safe_vars['end_date'])) + 60 * 60 * 24;
        }
           
        $table_obj = $this->db
            ->from('permission_log AS p')
            ->join('user AS u', 'p.u_id=u.id')
            ->join('class_func_description AS cf', 'p.cf_id=cf.id')
            ->where($where);

        $table_count_obj = clone $table_obj;

        // Record count
        $record_count = $table_count_obj->count_all_results();

        // Page process
        $per_page = $this->config->item('per_page');
        $this->load->helper('page');
        $pagination = oa_page($safe_vars['page'], $record_count, $per_page);

        // Get data 
        $query = $table_obj
            ->select('u.id, u.username, u.name, p.dateline, p.message, cf.name AS cf_name')
            ->order_by('p.dateline', 'desc')
            ->limit($per_page, $pagination['record_offset'])
            ->get();

        $log_info = $query->result_array();

        $this->load->view('permission_change_log_list', array(
            'log_info' => $log_info,
            'pagination' => $pagination,
            'safe_vars' => $safe_vars,
        ));
    }
    
    /**
     * @name 用户访问日志
     * @desc 用户访问日志
     */
    public function access_log_list()
    {
    	list($vars) = $this->check(array(
    		'page' => FC_int('page', 1)->min(1)
    	));
    	
    	$per_page = 10;
    	$data = array();
    	
    	$this->load->helper('page');
    	$data['pagination'] = oa_page(
    		$vars['page'], 
    		$this->db->count_all_results('access_log'), 
    		$per_page);
    	
    	$data['list'] = $this->db
    		->from('access_log')
    		->join('user', 'access_log.user_id=user.id')
    		->limit($per_page, $data['pagination']['record_offset'])
    		->get()->result_array();
    	
    	$this->load->view('permission_access_log_list', $data);
    }


    /**
     * @name 部门列表
     * @desc 权限模块，部门列表
     */
    public function department_list()
    {
        // Get department
        $query = $this->db->from('department')->order_by('displayorder')->get();

        $department_info = $query->result_array();
        $config_department = $this->config->item('department');

        $this->load->view('permission_department_list', array(
            'department_info' => $department_info,
            'preset_department' => $config_department['preset'],
            'token_name' => $this->security->get_csrf_token_name(),
            'token_hash' => $this->security->get_csrf_hash(),
        ));
    }


    /**
     * @name 添加部门页面加载
     * @desc 权限模块，新增部门加载页面
     */
    public function department_add_page()
    {
        $this->load->library('user_agent');
        $this->load->view('permission_department_add_page', array(
            'return_url' => $this->agent->referrer(),
            'token_name' => $this->security->get_csrf_token_name(),
            'token_hash' => $this->security->get_csrf_hash(),
        ));
    }


    /**
     * @name 添加部门
     * @desc 权限模块，新增部门
     * @method post
     */
    public function department_add()
    {
        list($safe_vars) = $this->check(array(
            'name' => FC_chs('部门名称')->min(2)->max(8)->required(),
            'return_url' => FC_str('返回地址', '')->max(255),
        ));

        $query = $this->db
            ->select('MAX(displayorder) AS max')
            ->from('department')
            ->get();
        
        $max = $query->first_row('array');
        $max = empty($max) ? 0 : $max['max'];

        $this->db->insert('department', array(
            'name' => $safe_vars['name'],
            'displayorder' => ++$max
        ));

        $this->load->view('info', array(
            'message' => '添加成功',
            'url' => $safe_vars['return_url'],
        ));
    }


    /**
     * @name 编辑部门
     * @desc 权限模块，编辑部门
     * @method post
     */
    public function department_edit()
    {
        //----------- Check user input begin ----------
        $department = $_POST['department'];
        if( ! is_array($department))
        {
            show_error('非法操作');
        }

        $format = array(
            'id' => FC_int('部门编号')->required(),
            'name' => FC_chs('部门名称')->min(2)->max(8)->required(),
        );

        $safe_vars = array();
        foreach($department as $id => $name)
        {
            list($data) = $this->check($format, array(
                'id' => strval($id),
                'name' => $name,
            ));

            $safe_vars[$data['id']] = $data['name'];
        }

        $config_department = $this->config->item('department');
        $preset_department = $config_department['preset'];
        if(empty($preset_department))
        {
            show_error('很抱歉，"其它部门"尚未创建，请联系管理员');
        }

        $query = $this->db
            ->select('id')
            ->from('department')
            ->where_not_in('id', $preset_department)
            ->get();
        $old_id_info = $query->result_array();
        $old_ids = array();
        foreach($old_id_info as $item)
        {
            $old_ids[] = $item['id'];
        }

        if( ! empty($safe_vars))
        {
            $valid_ids = array_intersect(array_keys($safe_vars), $old_ids);

            if(count($safe_vars) != count($valid_ids))
            {
                show_error('非法操作');
            }
        }

        //----------- Check user input end ------------
        
        $this->db->trans_start();

        // Process delete department
        $delete_ids = array_diff($old_ids, array_keys($safe_vars));
        if($delete_ids)
        {
            // All delete department user be reallocate to the first preset department
            $this->db
                ->where_in('department_id', $delete_ids)
                ->update('user', array(
                    'department_id' => $preset_department[0]
                ));

            $this->db->where_in('id', $delete_ids)->delete('department');
        }

        // Update valid department
        $index = 1;
        foreach($safe_vars as $id => $name)
        {
            $this->db->where('id', $id)->update('department', array(
                'name' => $name,
                'displayorder' => $index++
            ));
        }

        $this->db->trans_complete();

        // Show success info page
        $this->load->view('info', array(
            'message' => '编辑成功',
            'url' => '/perm/user/department/list',
        ));
    }
}


/* End of file: permission.php */
/* Location: ./application/controllers/permission.php */
